package com.cyanite.playlv2.widget;

import com.cyanite.playlv2.util.RemoteResourceManager;
import com.cyanite.playlv2api.types.Group;
import com.cyanite.playlv2api.types.Tip;
import com.cyanite.playlv2.R;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Observable;
import java.util.Observer;

public class TipsListAdapter extends BaseGroupAdapter<Tip>
    implements ObservableAdapter {

    private LayoutInflater mInflater;
    private int mLayoutToInflate;
    private Resources mResources;
    private RemoteResourceManager mRrm;
    private RemoteResourceManagerObserver mResourcesObserver;
    private Handler mHandler = new Handler();
    private int mLoadedPhotoIndex;
    private boolean mDisplayTipVenueTitles;
    private Map<String, String> mCachedTimestamps;

    public TipsListAdapter(Context context, RemoteResourceManager rrm, int layout) {
        super(context);
        mInflater = LayoutInflater.from(context);
        mLayoutToInflate = layout;
        mResources = context.getResources();
        mRrm = rrm;
        mResourcesObserver = new RemoteResourceManagerObserver();
        mLoadedPhotoIndex = 0;
        mDisplayTipVenueTitles = true;
        mCachedTimestamps = new HashMap<String, String>();

        mRrm.addObserver(mResourcesObserver);
    }

    public void removeObserver() {
        mHandler.removeCallbacks(mUpdatePhotos);
        mHandler.removeCallbacks(mRunnableLoadPhotos);
        mRrm.deleteObserver(mResourcesObserver);
    }

    public TipsListAdapter(Context context, int layoutResource) {
        super(context);
        mInflater = LayoutInflater.from(context);
        mLayoutToInflate = layoutResource;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        ViewHolder holder;
        if (convertView == null) {
            convertView = mInflater.inflate(mLayoutToInflate, null);

            holder = new ViewHolder();
            holder.photo = (ImageView) convertView.findViewById(R.id.icon);
            holder.title = (TextView) convertView.findViewById(R.id.tvTitle);
            holder.body = (TextView) convertView.findViewById(R.id.tvBody);
            holder.dateAndAuthor = (TextView) convertView.findViewById(R.id.tvDateAndAuthor);
            holder.corner = (ImageView) convertView.findViewById(R.id.ivTipCorner);

            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        Tip tip = (Tip) getItem(position);
        String url = tip.getUserPhoto();
        if (url != null && !url.equals("")) {
            Uri photoUri = Uri.parse(url);
            try {
                Bitmap bitmap = BitmapFactory.decodeStream(mRrm.getInputStream(photoUri));
                holder.photo.setImageBitmap(bitmap);
            } catch (IOException e) {
            }
        } else {
            /*Venue venue = tip.getVenue();
            VenueCategory category = venue.getCategory();
            if (category != null) {
                holder.photo.setBackgroundDrawable(null);
                holder.photo.setImageResource(category.getIconVenueRes());
            } else {
                holder.photo.setImageResource(R.drawable.venue_category_none);
            }*/
        }

        if (mDisplayTipVenueTitles && tip.getVenue() != null) {
            holder.title.setText("@ " + tip.getVenue().getName());
            holder.title.setVisibility(View.VISIBLE);
        } else {
            holder.title.setVisibility(View.GONE);

            holder.body.setPadding(
        		 holder.body.getPaddingLeft(), holder.title.getPaddingTop(),
        		 holder.body.getPaddingRight(), holder.title.getPaddingBottom());
        }

        holder.body.setText(tip.getShout());
        holder.dateAndAuthor.setText(mCachedTimestamps.get(tip.getId()));
        if (tip.getUserName() != null) {
            holder.dateAndAuthor.setText(
                    holder.dateAndAuthor.getText() +
                    mResources.getString(
                            R.string.tip_age_via,
                            tip.getUserName()));
        }
        /*
        if (tip.getStats().getTodoCount() > 0) {
            holder.friendCountTodoImg.setVisibility(View.VISIBLE);
            holder.friendCountTodo.setVisibility(View.VISIBLE);
            holder.friendCountTodo.setText(String.valueOf(tip.getStats().getTodoCount()));
        } else {
            holder.friendCountTodoImg.setVisibility(View.GONE);
            holder.friendCountTodo.setVisibility(View.GONE);
        }
        

        if (TipUtils.isDone(tip)) {
            holder.corner.setVisibility(View.VISIBLE);
            holder.corner.setImageResource(R.drawable.tip_list_item_corner_done);
        } else if (TipUtils.isTodo(tip)) {
            holder.corner.setVisibility(View.VISIBLE);
            holder.corner.setImageResource(R.drawable.tip_list_item_corner_todo);
        } else {
            holder.corner.setVisibility(View.GONE);
        }
        */
        return convertView;
    }

    public void removeItem(int position) throws IndexOutOfBoundsException {
        group.remove(position);
        notifyDataSetInvalidated();
    }

    @Override
    public void setGroup(Group<Tip> g) {
        super.setGroup(g);
        mLoadedPhotoIndex = 0;

        mHandler.postDelayed(mRunnableLoadPhotos, 10L);

        mCachedTimestamps.clear();
        /*
        for (Tip it : g) {
            String formatted = StringFormatters.getTipAge(mResources, it.getPostDate());
            mCachedTimestamps.put(it.getId(), formatted);
        }
        */
    }

    public void setDisplayTipVenueTitles(boolean displayTipVenueTitles) {
        mDisplayTipVenueTitles = displayTipVenueTitles;
    }

    private class RemoteResourceManagerObserver implements Observer {
        @Override
        public void update(Observable observable, Object data) {
            mHandler.post(mUpdatePhotos);
        }
    }

    private Runnable mUpdatePhotos = new Runnable() {
        @Override
        public void run() {
            notifyDataSetChanged();
        }
    };

    private Runnable mRunnableLoadPhotos = new Runnable() {
        @Override
        public void run() {
            if (mLoadedPhotoIndex < getCount()) {
                Tip tip = (Tip)getItem(mLoadedPhotoIndex++);
                String url = tip.getUserPhoto();
                if (url != null && !url.equals("")) {
                    Uri photoUri = Uri.parse(url);
                    if (!mRrm.exists(photoUri)) {
                        mRrm.request(photoUri);
                    }
                    mHandler.postDelayed(mRunnableLoadPhotos, 200L);
                }
            }
        }
    };

    static class ViewHolder {
        ImageView photo;
        TextView title;
        TextView body;
        TextView dateAndAuthor;
        ImageView corner;
    }
}
